home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / mailconf / mtable.c < prev   
C/C++ Source or Header  |  1996-07-01  |  6KB  |  275 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include "internal.h"
  5. #include "../netconf/netconf.h"
  6. #include "../paths.h"
  7. #include "mailconf.h"
  8. #include "mailconf.m"
  9.  
  10. static MAILCONF_HELP_FILE help_mailtable ("mailtable");
  11.  
  12. static CONFIG_FILE f_mailtable (VAR_LIB_MAILERTABLE,help_mailtable
  13.     ,CONFIGF_MANAGED|CONFIGF_OPTIONNAL);
  14.  
  15. PUBLIC SPC_ROUTE::SPC_ROUTE()
  16. {
  17.     subdomain = 0;
  18. }
  19.  
  20. PUBLIC void SPC_ROUTE::write (FILE *fout)
  21. {
  22.     fprintf (fout,"%s %s:%s\n",to.get(),mailer.get(),forwarder.get());
  23.     if (subdomain){
  24.         fprintf (fout,".%s %s:%s\n",to.get(),mailer.get()
  25.             ,forwarder.get());
  26.     }
  27. }
  28.  
  29.  
  30. /*
  31.     Edit one routing and return 0 if edit was success
  32.     Return 1 if the entry must be deleted.
  33. */
  34. PUBLIC int SPC_ROUTE::edit()
  35. {
  36.     DIALOG dia;
  37.     dia.newf_str (MSG_U(F_DEST,"Destination"),to);
  38.     dia.newf_str (MSG_U(F_FORWARD,"Forwader"),forwarder);
  39.     dia.newf_chk ("",subdomain,MSG_U(F_MANAGE,"Manage sub-domain identically"));
  40.     FIELD_COMBO *com = dia.newf_combo (MSG_U(F_MAILER,"Mailer"),mailer);
  41.     basic_setmailer (com);
  42.     int ret = -1;
  43.     int nof = 0;
  44.     while (1){
  45.         MENU_STATUS code = dia.edit (MSG_U(T_SPECIAL,"Special routing")
  46.             ,MSG_U(I_SPECIAL
  47.              ,"Enter a destination (host) and the\n"
  48.               "forwarder (another host) used to reach it\n"
  49.               "and the mailer (transport) needed")
  50.             ,help_mailtable.getpath()
  51.             ,nof
  52.             ,MENUBUT_DEL|MENUBUT_ACCEPT|MENUBUT_CANCEL);
  53.         if (code == MENU_CANCEL || code == MENU_ESCAPE){
  54.             break;
  55.         }else if (code == MENU_DEL){
  56.             ret = 1;
  57.             break;
  58.         }else{
  59.             if (to.is_empty()
  60.                 || forwarder.is_empty()
  61.                 || mailer.is_empty()){
  62.                 xconf_error (MSG_U(E_EMPTYF,"All field must be filled"));
  63.             }else{
  64.                 ret = 0;
  65.                 break;
  66.             }
  67.         }
  68.     }
  69.     if (ret != 0) dia.restore();
  70.     return ret;
  71. }
  72.  
  73.  
  74. PUBLIC SPC_ROUTES::SPC_ROUTES()
  75. {
  76.     /* #Specification: mailconf / special routing
  77.         A lookup file may be used by sendmail to managed
  78.         the routing of certain site. This file is called
  79.         the mailer table. Mostly, if the destination
  80.         match one entry of this table, the value pair
  81.         mailer:forwarder will be used.
  82.  
  83.         This ascii file must be turned into a database so
  84.         sendmail can use it efficiently. This is normally
  85.         done using the makemap utility.
  86.  
  87.         mailconf will always generate this file even if it
  88.         is empty. One reason is to simplify the generation
  89.         of the sendmail.cf file.
  90.     */
  91.     FILE *fin = f_mailtable.fopen ("r");
  92.     if (fin != NULL){
  93.         char buf[500];
  94.         int noline = 0;
  95.         while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
  96.             noline++;
  97.             strip_end (buf);
  98.             char *pt = str_skip (buf);
  99.             if (pt[0] != '\0'){
  100.                 char word[300];
  101.                 pt = str_copyword(word,pt);
  102.                 SPC_ROUTE *rt = new SPC_ROUTE;
  103.                 rt->to.setfrom (word);
  104.                 pt = str_skip(pt);
  105.                 if (pt[0] != '\0'){
  106.                     str_copyword(word,pt);
  107.                     pt = strchr(word,':');
  108.                     if (pt != NULL){
  109.                         *pt++ = '\0';
  110.                         rt->mailer.setfrom(word);
  111.                         rt->forwarder.setfrom(pt);
  112.                         add (rt);
  113.                     }
  114.                 }
  115.             }
  116.         }
  117.         fclose (fin);
  118.         /* #Specification: mailconf / mailertable / domain and subdomain
  119.             We can specify a different special routing for a
  120.             domain, and for subdomain in the mailer table.
  121.             This is done with two separate line:
  122.  
  123.             #
  124.             foo.com        mailer:forwarder
  125.             .foo.com    mailer:forwarder
  126.             #
  127.  
  128.             The first line manage foo.com and the other
  129.             everything else under it.
  130.  
  131.             mailconf present this information in a single
  132.             record. A checkbox let specify if we want to
  133.             manage the subdomain identically. This is
  134.             simpler to understand for administrator.
  135.  
  136.             The information is still written as two separate
  137.             line in the mailertable and fold back into
  138.             a single one when read
  139.         */
  140.         for (int i=0; i<getnb(); i++){
  141.             SPC_ROUTE *rt = getitem(i);
  142.             const char *to = rt->to.get();
  143.             if (to[0] != '.'){
  144.                 for (int j=0; j<getnb(); j++){
  145.                     SPC_ROUTE *rtf = getitem(j);
  146.                     const char *tof = rtf->to.get();
  147.                     if (tof[0] == '.'
  148.                         && strcmp(to,tof+1)==0
  149.                         && rt->mailer.cmp(rtf->mailer)==0
  150.                         && rt->forwarder.cmp(rtf->forwarder)==0){
  151.                         // Ok, we have found the same record, but applying
  152.                         // to subdomain.
  153.                         // We set the subdomain flag in rt and delete
  154.                         // this record
  155.                         rt->subdomain = 1;
  156.                         remove_del (rtf);
  157.                         if (j < i) i--;
  158.                         break;
  159.                     }
  160.                 }
  161.             }
  162.         }
  163.     }
  164. }
  165.  
  166. /*
  167.     Write the mailertable back.
  168. */
  169. PUBLIC int SPC_ROUTES::save()
  170. {
  171.     int ret = -1;
  172.     FILE *fout = f_mailtable.fopen ("w");
  173.     if (fout != NULL){
  174.         int nb = getnb();
  175.         for (int i=0; i<nb; i++) getitem(i)->write(fout);
  176.         fclose (fout);
  177.     }
  178.     return ret;
  179. }
  180.  
  181. /*
  182.     Write the mailertable back and rebuild the database
  183. */
  184. PUBLIC int SPC_ROUTES::build(
  185.     const char *dbformat)    // Format to used (btree, dbm)
  186.                 // If NULL, won't rebuild the database
  187. {
  188.     int ret = -1;
  189.     if (dbformat != NULL){
  190.         // This save simply insure that the file exist
  191.         // The constructor of SPC_ROUTES will manage a missing
  192.         // mailertable as an empty one. Given that the sendmail.cf
  193.         // refer to it all the time, we force a generation of the file
  194.         save();
  195.         char buf[300];
  196.         sprintf (buf,"%s %s <%s"
  197.             ,dbformat
  198.             ,f_mailtable.getpath()
  199.             ,f_mailtable.getpath());
  200.         ret = netconf_system_if ("makemap",buf);
  201.     }
  202.     return ret;
  203. }
  204.  
  205.  
  206. PUBLIC SPC_ROUTE *SPC_ROUTES::getitem(int no)
  207. {
  208.     return (SPC_ROUTE *)ARRAY::getitem(no);
  209. }
  210.  
  211.  
  212. static int cmp(const ARRAY_OBJ *p1, const ARRAY_OBJ *p2)
  213. {
  214.     SPC_ROUTE *r1 = (SPC_ROUTE *)p1;
  215.     SPC_ROUTE *r2 = (SPC_ROUTE *)p2;
  216.     return r1->to.cmp(r2->to);
  217. }
  218.  
  219. PUBLIC void SPC_ROUTES::sort()
  220. {
  221.     ARRAY::sort (cmp);
  222. }
  223.  
  224.  
  225. /*
  226.     Edit the special routings database.
  227.     Return 0 if the something was changed in the database.
  228. */
  229. PUBLIC int SPC_ROUTES::edit ()
  230. {
  231.     int ret = -1;
  232.     while (1){
  233.         sort();
  234.         int nb = getnb();
  235.         MENU_STATUS code;
  236.         int choice = 0;
  237.         {
  238.             DIALOG dia;
  239.             for (int i=0; i<nb; i++){
  240.                 SPC_ROUTE *rt = getitem(i);
  241.                 dia.new_menuitem (" ",rt->to.get());
  242.             }
  243.             dia.addwhat (MSG_U(I_ADDONE,"one routing spec"));
  244.             code = dia.editmenu (
  245.                 MSG_U(T_SPECIALS,"Special routings")
  246.                 ,MSG_U(I_SPECIALS,"You are allowed to edit/add/remove routings\n")
  247.                 ,help_mailtable
  248.                 ,choice
  249.                 ,MENUBUT_ADD);
  250.         }
  251.         if (code == MENU_QUIT || code == MENU_ESCAPE){
  252.             break;
  253.         }else if (code == MENU_ADD){
  254.             SPC_ROUTE *spc = new SPC_ROUTE;
  255.             if (spc->edit()==0){
  256.                 add (spc);
  257.                 save();
  258.                 ret = 0;
  259.             }else{
  260.                 delete spc;
  261.             }
  262.         }else if (nb > 0){
  263.             SPC_ROUTE *spc = getitem(choice);
  264.             int status = spc->edit();
  265.             if (status != -1){
  266.                 if (status == 1) remove_del(spc);
  267.                 save();
  268.                 ret = 0;
  269.             }
  270.         }
  271.     }
  272.     return ret;
  273. }
  274.  
  275.